package com.colt.contentcenter.mq.rocketmq;

import com.alibaba.fastjson.JSON;
import com.colt.contentcenter.dao.rocketmqtransactionlog.RocketmqTransactionLogMapper;
import com.colt.contentcenter.domain.dto.content.ShareAuditDTO;
import com.colt.contentcenter.domain.entity.rocketmqtransactionlog.RocketmqTransactionLog;
import com.colt.contentcenter.service.share.ShareService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;

/**
 * @program: content-center
 * @description: rocketMq添加积分事务监听
 * @author: colt
 * @create: 2020-08-31 14:52
 **/
@Slf4j
@RocketMQTransactionListener(txProducerGroup = "tx-add-bonus-group")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AddBonusTransactionListener implements RocketMQLocalTransactionListener {
    private final ShareService shareService;
    private final RocketmqTransactionLogMapper rocketmqTransactionLogMapper;
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object arg) {
        /**
        * @Description:  执行本地事务
        * @Param: [message, arg]
        * @return: org.apache.rocketmq.spring.core.RocketMQLocalTransactionState
        * @Author: colt
        * @Date: 2020/11/7
        */
        MessageHeaders headers = message.getHeaders();
        String transactionId = headers.get(RocketMQHeaders.TRANSACTION_ID).toString();
        Integer shareId = Integer.parseInt(headers.get("shareId").toString());

        //有个小坑，此为字符串非对象
       // Object dto = headers.get("dto");
        String dto = (String) headers.get("dto");
        ShareAuditDTO shareAuditDTO = JSON.parseObject(dto, ShareAuditDTO.class);

        try {
//            表示本地事务执行成功 mq提交事务消息
            this.shareService.auditByIdWithRocketMqLog(shareId,shareAuditDTO,transactionId);
            log.info("SUCCESS");
            return RocketMQLocalTransactionState.COMMIT;
        }catch (Exception e){
//            本地事务执行失败，事务回滚
            log.info("FAILD");
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }


    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        /**
        * @Description: 本地事务检查接口，通过检查事务日志记录表rocketmq_transaction_log,
         * 获取本地事务执行记录状态（成功或者失败）
        * @Param: [message]
        * @return: org.apache.rocketmq.spring.core.RocketMQLocalTransactionState
        * @Author: colt
        * @Date: 2020/11/7
        */
        MessageHeaders headers = message.getHeaders();
        String transactionId = headers.get(RocketMQHeaders.TRANSACTION_ID).toString();
        //select * from xx where transcaction_id = xxx
//          检查本地事务状态
        RocketmqTransactionLog rocketmqTransactionLog = this.rocketmqTransactionLogMapper.selectOne(
                RocketmqTransactionLog.builder()
                        .transactionId(transactionId).build()
        );
        if (rocketmqTransactionLog!=null){
            return RocketMQLocalTransactionState.COMMIT;
        }
        return RocketMQLocalTransactionState.ROLLBACK;
    }
}
